home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 41 / Amiga Format CD41 (1999-06)(Future Publishing)(GB)[!][issue 1999-07].iso / -seriously_amiga- / programming / other / gtlayout / source / ltp_determinesize.c < prev    next >
C/C++ Source or Header  |  1999-04-19  |  26KB  |  1,076 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1998 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #include "Assert.h"
  15.  
  16. LONG
  17. LTP_GetPickerWidth(
  18.     LONG    fontHeight,
  19.     LONG    aspectX,
  20.     LONG    aspectY)
  21. {
  22.     LONG margin,width;
  23.  
  24.     width = (fontHeight * aspectY) / aspectX;
  25.  
  26.     if(width < 8)
  27.         width = 8;
  28.  
  29.     margin = 2 + (width + 15) / 16;
  30.  
  31.     return((LONG)(margin + (((115 * width) / 150) & ~1) + 1 + margin));
  32. }
  33.  
  34. LONG
  35. LTP_GetPickerSize(LayoutHandle *Handle)
  36. {
  37.     return(LTP_GetPickerWidth(Handle->TextAttr->ta_YSize,Handle->AspectX,Handle->AspectY));
  38. }
  39.  
  40. VOID
  41. LTP_DetermineSize(LayoutHandle *Handle,ObjectNode *Node)
  42. {
  43.     if(!Handle->Failed)
  44.     {
  45.         LONG i,Len,Width,Max,Plus;
  46.  
  47.         if(Node->Label)
  48.         {
  49.             LONG LabelWidth = LT_LabelWidth(Handle,Node->Label);
  50.  
  51.             if(Node->LabelChars * Handle->GlyphWidth > LabelWidth)
  52.                 LabelWidth = Node->LabelChars * Handle->GlyphWidth;
  53.  
  54.             Node->LabelWidth = LabelWidth;
  55.         }
  56.         else
  57.             Node->LabelWidth = 0;
  58.  
  59.         switch(Node->Type)
  60.         {
  61.             #ifdef DO_BOOPSI_KIND
  62.             {
  63.                 case BOOPSI_KIND:
  64.  
  65.                     if(Node->Special.BOOPSI.ExactWidth)
  66.                         Node->Width = Node->Special.BOOPSI.ExactWidth;
  67.                     else
  68.                         Node->Width = Node->Chars * Handle->GlyphWidth;
  69.  
  70.                     if(Node->Special.BOOPSI.ExactHeight)
  71.                         Node->Height = Node->Special.BOOPSI.ExactHeight;
  72.                     else
  73.                         Node->Height = Node->Lines * Handle->GlyphHeight;
  74.  
  75.                     if(Node->Special.BOOPSI.RelFontHeight)
  76.                         Node->Height = Handle->GlyphHeight + Node->Special.BOOPSI.RelFontHeight;
  77.  
  78.                     break;
  79.             }
  80.             #endif    /* DO_BOOPSI_KIND */
  81.  
  82.             #ifdef DO_LEVEL_KIND
  83.             {
  84.                 case LEVEL_KIND:
  85.  
  86.                     if(Node->Special.Level.Freedom == FREEHORIZ)
  87.                     {
  88.                         Node->Width        = 6 + Node->Chars * Handle->GlyphWidth + 6;
  89.                         Node->Height    = LTP_QuerySliderSize(Handle->DrawInfo,Handle->GlyphHeight,FREEHORIZ,Node->Special.Level.Ticks);
  90.                     }
  91.                     else
  92.                     {
  93.                         Node->Height    = Node->Lines * Handle->GlyphHeight;
  94.                         Node->Width        = LTP_QuerySliderSize(Handle->DrawInfo,Handle->GlyphHeight,FREEVERT,Node->Special.Level.Ticks);
  95.                     }
  96.  
  97.                     if(Node->DefaultSize && Node->Height < 3 + Handle->GlyphHeight + 3)
  98.                         Node->Height = 3 + Handle->GlyphHeight + 3;
  99.  
  100.                     LTP_GetStorage(Node);
  101.  
  102.                     if(Node->Current > Node->Max)
  103.                     {
  104.                         Node->Current = Node->Max;
  105.  
  106.                         LTP_PutStorage(Node);
  107.                     }
  108.  
  109.                     if(Node->Current < Node->Min)
  110.                     {
  111.                         Node->Current = Node->Min;
  112.  
  113.                         LTP_PutStorage(Node);
  114.                     }
  115.  
  116.                     if(!Node->Special.Level.MaxLevelWidth || Handle->Rescaled)
  117.                     {
  118.                         LTP_LevelWidth(Handle,Node->Special.Level.LevelFormat,Node->Special.Level.DispFunc,Node->Min,Node->Max,&Node->Special.Level.MaxLevelWidth,NULL,Node->Special.Level.FullLevelCheck);
  119.  
  120.                         Node->Special.Level.MaxLevelWidth += TextLength(&Handle->RPort," ",1);
  121.                     }
  122.  
  123.                     if(!Node->Special.Level.Plus)
  124.                         Node->Special.Level.Plus = Node->Min;
  125.  
  126.                     if(Node->LabelChars * Handle->GlyphWidth > Node->LabelWidth)
  127.                         Node->LabelWidth = Node->LabelChars * Handle->GlyphWidth;
  128.  
  129.                     if(Node->Special.Level.LevelPlace == PLACETEXT_LEFT &&
  130.                        Node->LabelPlace == PLACE_LEFT &&
  131.                        Node->Special.Level.LevelFormat != NULL)
  132.                     {
  133.                         Node->LabelWidth += Node->Special.Level.MaxLevelWidth;
  134.                     }
  135.  
  136.                     break;
  137.             }
  138.             #endif    /* DO_LEVEL_KIND */
  139.  
  140.             case GROUP_KIND:
  141.  
  142.                 LTP_LayoutGroup(Handle,Node);
  143.  
  144.                 break;
  145.  
  146.             case XBAR_KIND:
  147.  
  148.                 Node->Width        = Handle->GlyphWidth;
  149.                 Node->Height    = 6;
  150.  
  151.                 break;
  152.  
  153.             case YBAR_KIND:
  154.  
  155.                 Node->Width        = 6;
  156.                 Node->Height    = Handle->GlyphHeight;
  157.  
  158.                 if(Node->DefaultSize)
  159.                     Node->Height = 3 + Handle->GlyphHeight + 3;
  160.  
  161.                 break;
  162.  
  163.             case IMAGE_KIND:
  164.  
  165.                 if(Node->Special.Image.Image != NULL)
  166.                 {
  167.                     Node->Width        = Node->Special.Image.Image->Width;
  168.                     Node->Height    = Node->Special.Image.Image->Height;
  169.                 }
  170.                 else if (Node->Special.Image.BitMap != NULL)
  171.                 {
  172.                     Node->Width        = Node->Special.Image.BitMapWidth;
  173.                     Node->Height    = Node->Special.Image.BitMapHeight;
  174.                 }
  175.                 else
  176.                 {
  177.                     Handle->Failed = TRUE;
  178.                 }
  179.  
  180.                 break;
  181.  
  182.             case FRAME_KIND:
  183.             {
  184.                 LONG Width    = Node->Special.Frame.InnerWidth;
  185.                 LONG Height    = Node->Special.Frame.InnerHeight;
  186.  
  187.                 if(Node->Special.Frame.PlusWidth > 0 || Node->Special.Frame.PlusHeight > 0)
  188.                 {
  189.                     Width    += Node->Special.Frame.PlusWidth * Handle->GlyphWidth;
  190.                     Height    += Node->Special.Frame.PlusHeight * Handle->GlyphHeight;
  191.                 }
  192.  
  193.                 if(Node->Special.Frame.DrawBox)
  194.                 {
  195.                     Node->Width        = 4 + Width + 4;
  196.                     Node->Height    = 2 + Height + 2;
  197.                 }
  198.                 else
  199.                 {
  200.                     Node->Width        = Width;
  201.                     Node->Height    = Height;
  202.                 }
  203.  
  204.                 break;
  205.             }
  206.  
  207.             case BOX_KIND:
  208.  
  209.                 Node->LabelWidth = 0;
  210.  
  211.                 if(Node->Special.Box.Labels)
  212.                 {
  213.                     for(i = 0 ; i < Node->Lines ; i++)
  214.                     {
  215.                         if((Width = TextLength(&Handle->RPort,Node->Special.Box.Labels[i],strlen(Node->Special.Box.Labels[i]))) > Node->LabelWidth)
  216.                             Node->LabelWidth = Width;
  217.                     }
  218.                 }
  219.  
  220.                 if(Node->LabelChars)
  221.                 {
  222.                     if(Node->LabelChars * Handle->GlyphWidth > Node->LabelWidth)
  223.                         Node->LabelWidth = Node->LabelChars * Handle->GlyphWidth;
  224.                     else
  225.                         Node->LabelWidth = ((Node->LabelWidth + Node->LabelChars - 1) / Node->LabelChars) * Node->LabelChars;
  226.                 }
  227.  
  228.                 Max = Node->Chars;
  229.  
  230.                 if(Node->Special.Box.Lines)
  231.                 {
  232.                     LONG MaxWidth = 0;
  233.  
  234.                     for(i = 0 ; i < Node->Lines ; i++)
  235.                     {
  236.                         if(Node->Special.Box.Lines[i])
  237.                         {
  238.                             if(Len = strlen(Node->Special.Box.Lines[i]))
  239.                             {
  240.                                 if((Width = TextLength(&Handle->RPort,Node->Special.Box.Lines[i],Len)) > MaxWidth)
  241.                                     MaxWidth = Width;
  242.                             }
  243.                         }
  244.                     }
  245.  
  246.                     if(Max < (MaxWidth + Handle->GlyphWidth - 1) / Handle->GlyphWidth)
  247.                         Max = (MaxWidth + Handle->GlyphWidth - 1) / Handle->GlyphWidth;
  248.                 }
  249.  
  250.                 Node->Height    = 2 + Node->Lines * (Handle->GlyphHeight + Node->Special.Box.Spacing) + 2;
  251.                 Node->Width        = 4 + Max * Handle->GlyphWidth + 4;
  252.  
  253.                 if(Node->DefaultSize)
  254.                     Node->Height = 3 + Node->Lines * (Handle->GlyphHeight + Node->Special.Box.Spacing) + 3;
  255.  
  256.                 Node->Height -= Node->Special.Box.Spacing;
  257.  
  258.                 break;
  259.  
  260.             case BLANK_KIND:
  261.  
  262.                 Node->Width            = Handle->GlyphWidth * max(1,Node->Chars);
  263.                 Node->Height        = Handle->GlyphHeight;
  264.                 Node->Label            = "";
  265.                 Node->LabelWidth    = 0;
  266.                 Node->LabelPlace    = PLACE_IN;
  267.  
  268.                 if(Node->DefaultSize)
  269.                     Node->Height = 3 + Handle->GlyphHeight + 3;
  270.  
  271.                 break;
  272.  
  273.             case BUTTON_KIND:
  274.  
  275.                 if(!Node->Special.Button.Lines && Node->Label)
  276.                 {
  277.                     LONG i,Len = strlen(Node->Label),Count = 0;
  278.  
  279.                     for(i = 0 ; i < Len ; i++)
  280.                     {
  281.                         if(Node->Label[i] == '\n')
  282.                             Count++;
  283.                     }
  284.  
  285.                     if(Count)
  286.                     {
  287.                         STRPTR *Lines;
  288.  
  289.                         if(Lines = (STRPTR *)LTP_Alloc(Handle,(Count + 2) * sizeof(STRPTR) + Len + 1))
  290.                         {
  291.                             STRPTR String = (STRPTR)(&Lines[Count + 2]);
  292.  
  293.                             strcpy(String,Node->Label);
  294.  
  295.                             Node->Special.Button.Lines = Lines;
  296.  
  297.                             if(Node->Special.Button.KeyStroke)
  298.                                 Node->Special.Button.KeyStroke = &String[((ULONG)Node->Special.Button.KeyStroke) - ((ULONG)Node->Label)];
  299.  
  300.                             do
  301.                             {
  302.                                 *Lines++ = String;
  303.  
  304.                                 for(i = 0 ; String[i] ; i++)
  305.                                 {
  306.                                     if(String[i] == '\n')
  307.                                     {
  308.                                         String[i] = 0;
  309.  
  310.                                         String = &String[i + 1];
  311.  
  312.                                         break;
  313.                                     }
  314.                                 }
  315.                             }
  316.                             while(Count--);
  317.                         }
  318.                         else
  319.                             break;
  320.  
  321.                         LTP_ReplaceLabelShortcut(Handle,Node);
  322.                     }
  323.                 }
  324.  
  325.                 if(Node->Special.Button.Lines)
  326.                 {
  327.                     STRPTR    *Index = Node->Special.Button.Lines;
  328.                     LONG     Count = 0,Width,MaxWidth = 0,Height;
  329.  
  330.                     while(*Index)
  331.                     {
  332.                         Count++;
  333.  
  334.                         if((Width = LT_LabelWidth(Handle,*Index)) > MaxWidth)
  335.                             MaxWidth = Width;
  336.  
  337.                         Index++;
  338.                     }
  339.  
  340.                     Node->Special.Button.LineCount = Count;
  341.  
  342.                     if(Node->Chars * Handle->GlyphWidth > MaxWidth)
  343.                         MaxWidth = Node->Chars * Handle->GlyphWidth;
  344.  
  345.                     if(Node->Lines > Count)
  346.                         Count = Node->Lines;
  347.  
  348.                     Height = Count * Handle->GlyphHeight;
  349.  
  350.                     if(Node->Special.Button.ExtraFat)
  351.                     {
  352.                         Node->Width        = 6 + Handle->GlyphWidth + MaxWidth + Handle->GlyphWidth + 6;
  353.                         Node->Height    = 2 + (2 * Height + Handle->GlyphHeight) / 2 + 2;
  354.                     }
  355.                     else
  356.                     {
  357.                         if(Node->Special.Button.Smaller)
  358.                         {
  359.                             Node->Width        = 4 + MaxWidth + 4;
  360.                             Node->Height    = 2 + Height + 2;
  361.                         }
  362.                         else
  363.                         {
  364.                             Node->Width        = 6 + MaxWidth + 6;
  365.                             Node->Height    = 3 + Height + 3;
  366.                         }
  367.                     }
  368.  
  369.                     Node->Label = "";
  370.                 }
  371.                 else
  372.                 {
  373.                     if(Node->Chars * Handle->GlyphWidth > Node->LabelWidth)
  374.                         Node->Width = Node->Chars * Handle->GlyphWidth;
  375.                     else
  376.                         Node->Width = Node->LabelWidth;
  377.  
  378.                     if(Node->Lines)
  379.                     {
  380.                         if(Node->Special.Button.ExtraFat)
  381.                         {
  382.                             Node->Width        = 6 + Handle->GlyphWidth + Node->Width + Handle->GlyphWidth + 6;
  383.                             Node->Height    = 2 + ((Node->Lines + 1) * Handle->GlyphHeight) / 2 + 2;
  384.                         }
  385.                         else
  386.                         {
  387.                             if(Node->Special.Button.Smaller)
  388.                             {
  389.                                 Node->Width        = 4 + Node->Width + 4;
  390.                                 Node->Height    = 2 + (Node->Lines * Handle->GlyphHeight) + 2;
  391.                             }
  392.                             else
  393.                             {
  394.                                 Node->Width        = 6 + Node->Width + 6;
  395.                                 Node->Height    = 3 + (Node->Lines * Handle->GlyphHeight) + 3;
  396.                             }
  397.                         }
  398.                     }
  399.                     else
  400.                     {
  401.                         if(Node->Special.Button.ExtraFat)
  402.                         {
  403.                             Node->Width        = 6 + Handle->GlyphWidth + Node->Width + Handle->GlyphWidth + 6;
  404.                             Node->Height    = 2 + (3 * Handle->GlyphHeight) / 2 + 2;
  405.                         }
  406.                         else
  407.                         {
  408.                             if(Node->Special.Button.Smaller)
  409.                             {
  410.                                 Node->Width        = 4 + Node->Width + 4;
  411.                                 Node->Height    = 2 + Handle->GlyphHeight + 2;
  412.                             }
  413.                             else
  414.                             {
  415.                                 Node->Width        = 6 + Node->Width + 6;
  416.                                 Node->Height    = 3 + Handle->GlyphHeight + 3;
  417.                             }
  418.                         }
  419.                     }
  420.                 }
  421.  
  422.                 Node->LabelWidth = 0;
  423.                 Node->LabelPlace = PLACE_IN;
  424.  
  425.                 break;
  426.  
  427.             case CHECKBOX_KIND:
  428.  
  429.                 Node->Width = Node->Height = Handle->RPort.TxBaseline + ((Handle->RPort.TxBaseline + 2) / 3) * 2;
  430.  
  431.                 if(Node->Height < CHECKBOX_HEIGHT)
  432.                     Node->Height = CHECKBOX_HEIGHT;
  433.  
  434.                 if(Node->DefaultSize)
  435.                     Node->Height = 3 + Handle->GlyphHeight + 3;
  436.  
  437.                 if(!V39)
  438.                 {
  439.                     if(Node->Width < CHECKBOX_WIDTH)
  440.                         Node->Width = CHECKBOX_WIDTH;
  441.                 }
  442.                 else
  443.                     Node->Width = (Node->Height * Handle->AspectY) / Handle->AspectX;
  444.  
  445.                 break;
  446.  
  447.             case LISTVIEW_KIND:
  448.             {
  449.                 struct TextFont    *Font,*OldFont;
  450.                 LONG             GlyphWidth;
  451.  
  452.                 if(Node->Lines < 1)
  453.                 {
  454.                     Handle->Failed = TRUE;
  455.  
  456.                     return;
  457.                 }
  458.  
  459.                 if(Node->Special.List.TextAttr)
  460.                 {
  461.                     if(!(Font = LTP_OpenFont(Node->Special.List.TextAttr)))
  462.                     {
  463.                         Handle->Failed = TRUE;
  464.  
  465.                         return;
  466.                     }
  467.  
  468.                         // Is this a fixed-width font?
  469.  
  470.                     if(Font->tf_Flags & FPF_PROPORTIONAL)
  471.                     {
  472.                             // We don't want it
  473.  
  474.                         CloseFont(Font);
  475.  
  476.                         Handle->Failed = TRUE;
  477.  
  478.                         return;
  479.                     }
  480.  
  481.                     OldFont = Handle->RPort.Font;
  482.  
  483.                     SetFont(&Handle->RPort,Font);
  484.  
  485.                     GlyphWidth = Handle->RPort.TxWidth;
  486.  
  487.                     Node->Special.List.FixedGlyphWidth    = Handle->RPort.TxWidth;
  488.                     Node->Special.List.FixedGlyphHeight    = Handle->GlyphHeight;
  489.                 }
  490.                 else
  491.                 {
  492.                     Font        = NULL;
  493.                     OldFont        = NULL;    /* For the sake of the compiler, make sure this is initialized */
  494.                     GlyphWidth    = Handle->GlyphWidth;
  495.                 }
  496.  
  497.                 i        = 0;
  498.                 Max        = 0;
  499.                 Width    = Node->Chars * GlyphWidth;
  500.  
  501.                 if((ULONG)Node->Special.List.Labels == 0xFFFFFFFF)
  502.                     Node->Min = Node->Max = -1;
  503.                 else
  504.                 {
  505.                     if(Node->Special.List.Labels)
  506.                     {
  507.                         struct Node *Item;
  508.  
  509.                         SCANLIST(Node->Special.List.Labels,Item)
  510.                         {
  511.                             i++;
  512.  
  513.                             if((Len = TextLength(&Handle->RPort,Item->ln_Name,strlen(Item->ln_Name))) > Max)
  514.                                 Max = Len;
  515.                         }
  516.                     }
  517.  
  518.                     if(Node->Special.List.IgnoreListContents)
  519.                         Max = 0;
  520.  
  521.                     Node->Max = i - 1;
  522.                 }
  523.  
  524.                 if(Max > Width && !Node->Special.List.SizeLocked)
  525.                 {
  526.                     Width = Max;
  527.  
  528.                     Node->Chars = (Width + GlyphWidth - 1) / GlyphWidth;
  529.  
  530.                     Width = Node->Chars * GlyphWidth;
  531.                 }
  532.  
  533.                 if(Node->Special.List.LockSize)
  534.                     Node->Special.List.SizeLocked = TRUE;
  535.  
  536.                 if(!V39)
  537.                     Node->Width = (4 + Width + 4) + (2 + 2 * Handle->GlyphWidth + 2) + 8;
  538.                 else
  539.                     Node->Width = (4 + Width + 4) + (2 + 2 * Handle->GlyphWidth + 2);
  540.  
  541.                 Node->Height = 2 + Node->Lines * Handle->GlyphHeight + 2;
  542.  
  543.                 if(Node->Special.List.AdjustForString)
  544.                     Node->Height += Handle->InterHeight + 3 + Handle->GlyphHeight + 3;
  545.  
  546.                 if(Node->Special.List.ReadOnly)
  547.                 {
  548.                     if(Node->Special.List.LinkID != -1)
  549.                     {
  550.                         if(!V39)
  551.                             Node->Height += 2 + Handle->GlyphHeight + 2;
  552.                     }
  553.                 }
  554.                 else
  555.                 {
  556.                     if(Node->Special.List.LinkID == NIL_LINK)
  557.                     {
  558.                         if(!V39)
  559.                             Node->Height += 2 + Handle->GlyphHeight + 2;
  560.                     }
  561.                     else
  562.                     {
  563.                         if(Node->Special.List.LinkID != -1 && Node->Special.List.LinkID != NIL_LINK)
  564.                             Node->Height += 3 + Handle->GlyphHeight + 3;
  565.                     }
  566.                 }
  567.  
  568.                     // Switch back to the window font
  569.  
  570.                 if(Font)
  571.                 {
  572.                     SetFont(&Handle->RPort,OldFont);
  573.  
  574.                     CloseFont(Font);
  575.                 }
  576.  
  577.                 if(Node->Special.List.ExtraLabels)
  578.                 {
  579.                     for(i = Max = 0 ; Node->Special.List.ExtraLabels[i] ; i++)
  580.                     {
  581.                         if((Len = TextLength(&Handle->RPort,Node->Special.List.ExtraLabels[i],strlen(Node->Special.List.ExtraLabels[i]))) > Max)
  582.                             Max = Len;
  583.                     }
  584.  
  585.                     Node->Special.List.ExtraLabelWidth = Max;
  586.                 }
  587.  
  588.                 break;
  589.             }
  590.  
  591.             case MX_KIND:
  592.  
  593.                 i    = 0;
  594.                 Max    = 0;
  595.  
  596.                 while(Node->Special.Radio.Choices[i])
  597.                 {
  598.                     if((Width = TextLength(&Handle->RPort,Node->Special.Radio.Choices[i],strlen(Node->Special.Radio.Choices[i]))) > Max)
  599.                         Max = Width;
  600.  
  601.                     i++;
  602.                 }
  603.  
  604.                 Node->Max = i - 1;
  605.  
  606.                 Node->Special.Radio.LabelWidth = Max;
  607.  
  608.                 if(Node->LabelChars * Handle->GlyphWidth > Node->LabelWidth)
  609.                     Node->LabelWidth = Node->LabelChars * Handle->GlyphWidth;
  610.  
  611.                 Node->Height = max(MX_HEIGHT,Handle->GlyphHeight);
  612.  
  613.                 if(!V39)
  614.                     Node->Width = MX_WIDTH;
  615.                 else
  616.                 {
  617.                     Node->Width = (Node->Height * Handle->AspectY) / Handle->AspectX;
  618.  
  619.                     if(Node->Height < MX_HEIGHT)
  620.                     {
  621.                         Node->Height = MX_HEIGHT;
  622.                         Node->Width  = (Node->Height * Handle->AspectX) / Handle->AspectY;
  623.                     }
  624.                 }
  625.  
  626.                 Node->Lines  = i;
  627.                 Node->Height = Node->Lines * (Node->Height + Handle->InterHeight) - Handle->InterHeight;
  628.  
  629.                 break;
  630.  
  631.             #ifdef DO_GAUGE_KIND
  632.             {
  633.                 case GAUGE_KIND:
  634.  
  635.                     Width = TextLength(&Handle->RPort,"0%100%",6) + 2 * Handle->GlyphWidth;
  636.  
  637.                     if(Handle->GlyphWidth * Node->Chars > Width)
  638.                         Width = Handle->GlyphWidth * Node->Chars;
  639.  
  640.                     Node->Width = 6 + Width + 6;
  641.  
  642.                     if(Node->Special.Gauge.NoTicks)
  643.                         Node->Height = 3 + Handle->GlyphHeight + 3;
  644.                     else
  645.                         Node->Height = 3 + Handle->GlyphHeight + 2 + Handle->InterHeight + Handle->GlyphHeight + 3;
  646.  
  647.                     if(Node->Special.Gauge.Discrete)
  648.                     {
  649.                         Width = ((Node->Width - 6 - 6) + 9) / 10;
  650.  
  651.                         Node->Width = 2 + Width * 10 + 2;
  652.                     }
  653.  
  654.                     break;
  655.             }
  656.             #endif
  657.  
  658.             #ifdef DO_TAPEDECK_KIND
  659.             {
  660.                 case TAPEDECK_KIND:
  661.                 {
  662.                     LONG Width,Height,OrigWidth,Attempt = 4;
  663.  
  664.                     Width = TextLength(&Handle->RPort,"AA",2);
  665.  
  666.                     if(Width < 2 * Handle->GlyphWidth);
  667.                         Width = 2 * Handle->GlyphWidth;
  668.  
  669.                     if(Width < 2 * Handle->GlyphHeight)
  670.                         Width = 2 * Handle->GlyphHeight;
  671.  
  672.                     if(Node->Special.TapeDeck.Smaller)
  673.                         Width = (3 * Width) / 4;
  674.  
  675.                     if(Width & 1)
  676.                         Width++;
  677.  
  678.                     OrigWidth = Width;
  679.  
  680.                     do
  681.                     {
  682.                         Width    = 1 + ((((OrigWidth + 5) / 6) * 6) & ~1);
  683.                         Height    = (Handle->AspectX * Width) / (Handle->AspectY * 2);
  684.  
  685.                         OrigWidth += 2;
  686.                         Attempt--;
  687.                     }
  688.                     while(Height < 6 && Attempt > 0);
  689.  
  690.                     if(!(Height & 1))
  691.                         Height++;
  692.  
  693.                     if(Node->Special.TapeDeck.ButtonType == TDBT_BACKWARD || Node->Special.TapeDeck.ButtonType == TDBT_FORWARD)
  694.                         Node->Special.TapeDeck.ButtonWidth = Width;
  695.                     else
  696.                         Node->Special.TapeDeck.ButtonWidth = Width / 2;
  697.  
  698.                     Node->Special.TapeDeck.ButtonHeight = Height;
  699.  
  700.                     if(Handle->GlyphWidth * Node->Chars > Width)
  701.                         Width = Handle->GlyphWidth * Node->Chars;
  702.  
  703.                     Node->Width        = 6 + Width + 6;
  704.                     Node->Height    = 3 + Height + 3;
  705.  
  706.                     break;
  707.                 }
  708.             }
  709.             #endif    /* DO_TAPEDECK_KIND */
  710.  
  711.             case CYCLE_KIND:
  712.  
  713.                     // NOTE: This does not include the width of the
  714.                     //       cycle glyph which is by default 26 pixels
  715.                     //       wide.
  716.  
  717.                 Node->Width = 6 + Node->Chars * Handle->GlyphWidth + 6;
  718.  
  719.                 Width = 0;
  720.  
  721.                 if(Node->Special.Cycle.Choices)
  722.                 {
  723.                     for(i = 0 ; Node->Special.Cycle.Choices[i] ; i++)
  724.                     {
  725.                         if((Len = TextLength(&Handle->RPort,Node->Special.Cycle.Choices[i],strlen(Node->Special.Cycle.Choices[i]))) > Width)
  726.                             Width = Len;
  727.                     }
  728.  
  729.                     Node->Max = i - 1;
  730.                 }
  731.  
  732.                 Max = 6 + 20 + Width + 6;    /* Let's see if the interior is large enough for the glyph. */
  733.  
  734.                 if(Node->Width < Max)
  735.                     Node->Width = Max;
  736.  
  737.                     // Add the remainder of the cycle glyph
  738.  
  739.                 Node->Height = 3 + Handle->GlyphHeight + 3;
  740.  
  741.                 break;
  742.  
  743.             #ifdef DO_POPUP_KIND
  744.             {
  745.                 case POPUP_KIND:
  746.  
  747.                         // NOTE: This is the number of pixels the popup glyph
  748.                         //       will need. It will not enter the calculation
  749.                         //       until the maximum size of the hit box is
  750.                         //       calculated.
  751.  
  752.                     Plus = (4 + ((TextLength(&Handle->RPort,"M",1) & ~1) + 1) + 2 + 4) + (Handle->GlyphHeight * Handle->DrawInfo->dri_Resolution.Y) / Handle->DrawInfo->dri_Resolution.X + 2;
  753.  
  754.                     if(Plus < 20)
  755.                         Plus = 20;
  756.  
  757.                     Node->Width = 6 + Node->Chars * Handle->GlyphWidth + 6;
  758.  
  759.                     Width = 0;
  760.  
  761.                     if(Node->Special.Popup.Choices)
  762.                     {
  763.                         for(i = 0 ; Node->Special.Popup.Choices[i] ; i++)
  764.                         {
  765.                             Len = TextLength(&Handle->RPort,
  766.                                              Node->Special.Popup.Choices[i],
  767.                                              strlen(Node->Special.Popup.Choices[i]));
  768.                             if(Len > Width)
  769.                                 Width = Len;
  770.                         }
  771.  
  772.                         Node->Max = i - 1;
  773.                     }
  774.  
  775.                     Max = 6 + Plus + Width + 6;    /* Let's see if the interior is large enough for the glyph. */
  776.  
  777.                     if(Node->Width < Max)
  778.                         Node->Width = Max;
  779.  
  780.                         // Add the glyph width
  781.  
  782.                     Node->Height = 3 + Handle->GlyphHeight + 3;
  783.  
  784.                     break;
  785.             }
  786.             #endif
  787.  
  788.             #ifdef DO_TAB_KIND
  789.             {
  790.                 case TAB_KIND:
  791.  
  792.                     if(!Node->Special.Tab.Choices)
  793.                         Handle->Failed = TRUE;
  794.                     else
  795.                     {
  796.                         struct IBox Box;
  797.  
  798.                         Width = Node->Chars * Handle->GlyphWidth;
  799.  
  800.                         for(i = 0 ; Node->Special.Tab.Choices[i] ; i++);
  801.  
  802.                         Node->Max = i - 1;
  803.  
  804.                         Node->Label = NULL;
  805.  
  806.                         if(!LTP_ObtainTabSize(&Box,
  807.                             TIA_Labels,        Node->Special.Tab.Choices,
  808.                             TIA_DrawInfo,    Handle->DrawInfo,
  809.                             TIA_Font,        Handle->TextAttr,
  810.                             TIA_SizeType,    GDOMAIN_MINIMUM,
  811.                         TAG_DONE))
  812.                             Handle->Failed = TRUE;
  813.                         else
  814.                         {
  815.                             if(Width < Box.Width)
  816.                                 Width = Box.Width;
  817.  
  818.                             Node->Width        = Width;
  819.                             Node->Height    = Box.Height;
  820.                         }
  821.                     }
  822.  
  823.                     break;
  824.             }
  825.             #endif
  826.  
  827.             case PALETTE_KIND:
  828.  
  829.                 if(Node->Special.Palette.UsePicker)
  830.                 {
  831.                     Node->Height = 3 + Handle->GlyphHeight + 3;
  832.                     Node->Width = (Node->Height * Handle->AspectY) / Handle->AspectX;
  833.  
  834.                     Node->Special.Palette.IndicatorWidth = Node->Width;
  835.  
  836.                     Node->Width += LTP_GetPickerSize(Handle);
  837.                 }
  838.                 else
  839.                 {
  840.                     if(Node->Special.Palette.NumColours)
  841.                         Node->Max = Node->Min + Node->Special.Palette.NumColours - 1;
  842.                     else
  843.                     {
  844.                         if(!Node->Special.Palette.Depth)
  845.                             Node->Special.Palette.Depth = 1;
  846.  
  847.                         Node->Special.Palette.NumColours = 1L << Node->Special.Palette.Depth;
  848.  
  849.                         Node->Max = Node->Min + Node->Special.Palette.NumColours - 1;
  850.                     }
  851.  
  852.                     if(Node->Special.Palette.SmallPalette)
  853.                     {
  854.                         Node->Width        = Handle->GlyphWidth * (Node->Max - Node->Min + 1) + 4;
  855.                         Node->Height    = 1 + Handle->GlyphHeight + 1;
  856.  
  857.                         if((Node->Width - 4) / (Node->Max - Node->Min + 1) < 8 && Node->Height < 2 * 8)
  858.                             Node->Width = 8 * (Node->Max - Node->Min + 1) + 4;
  859.  
  860.                         Node->Width += 2 * Handle->GlyphWidth;
  861.                     }
  862.                     else
  863.                     {
  864.                         Node->Width        = 2 * Handle->GlyphWidth * (Node->Max - Node->Min + 1);
  865.                         Node->Height    = 2 * Handle->GlyphHeight;
  866.                     }
  867.  
  868.                     if(Node->Width < 20)
  869.                         Node->Width = 20;
  870.  
  871.                     if(Node->Chars * Handle->GlyphWidth > Node->Width)
  872.                         Node->Width = Node->Chars * Handle->GlyphWidth;
  873.  
  874.                     if(Node->Special.Palette.NumColours > 16)
  875.                     {
  876.                         Node->Height    *= 2;
  877.                         Node->Width        /= 2;
  878.                     }
  879.  
  880.                     if(Node->Lines)
  881.                     {
  882.                         if(!Node->Chars)
  883.                             Node->Width = Handle->GlyphWidth;
  884.                         else
  885.                             Node->Width = Node->Chars * Handle->GlyphWidth;
  886.  
  887.                         Node->Height = Node->Lines * Handle->GlyphHeight;
  888.                     }
  889.  
  890.                     if(Node->Special.Palette.ColourTable && !Node->Special.Palette.TranslateBack)
  891.                     {
  892.                         if(Node->Special.Palette.TranslateBack = LTP_Alloc(Handle,256))
  893.                         {
  894.                             LONG i;
  895.  
  896.                             for(i = Node->Min ; i <= Node->Max ; i++)
  897.                                 Node->Special.Palette.TranslateBack[Node->Special.Palette.ColourTable[i]] = i;
  898.                         }
  899.                     }
  900.                 }
  901.  
  902.                 break;
  903.  
  904.             case SCROLLER_KIND:
  905.  
  906.                 if(Node->Special.Scroller.Vertical)
  907.                 {
  908.                     if(Node->Special.Scroller.FullSize)
  909.                         Node->Lines = 1;
  910.  
  911.                     if(Node->Special.Scroller.Thin)
  912.                         Node->Width = 6 + Handle->GlyphWidth + 6;
  913.                     else
  914.                         Node->Width = 6 + (3 * Handle->GlyphWidth) / 2 + 6;
  915.  
  916.                     Node->Height = 2 + Node->Lines * Handle->GlyphHeight;
  917.  
  918.                     if(Node->Special.Scroller.Arrows)
  919.                     {
  920.                         LONG ScrollerHeight = (Handle->AspectX * Node->Width) / Handle->AspectY;
  921.  
  922.                         if(Node->Height < 2 + Node->Lines * Handle->GlyphHeight + 2 * ScrollerHeight)
  923.                             Node->Height = 2 + Node->Lines * Handle->GlyphHeight + 2 * ScrollerHeight;
  924.  
  925.                         Node->Special.Scroller.ArrowSize = ScrollerHeight;
  926.                     }
  927.                 }
  928.                 else
  929.                 {
  930.                     if(Node->Special.Scroller.FullSize)
  931.                         Node->Chars = 1;
  932.  
  933.                     Node->Width  = 6 + Node->Chars * Handle->GlyphWidth + 6;
  934.                     Node->Height = 2 + Handle->GlyphHeight;
  935.  
  936.                     if(Node->DefaultSize)
  937.                         Node->Height = 3 + Handle->GlyphHeight + 3;
  938.  
  939.                     if(Node->Special.Scroller.Arrows)
  940.                     {
  941.                         LONG ScrollerWidth = (Handle->AspectY * Node->Height) / Handle->AspectX;
  942.  
  943.                         if(Node->Width < 6 + Handle->GlyphWidth + 2 * ScrollerWidth + 6)
  944.                             Node->Width = 6 + Handle->GlyphWidth + 2 * ScrollerWidth + 6;
  945.  
  946.                         Node->Special.Scroller.ArrowSize = ScrollerWidth;
  947.                     }
  948.                 }
  949.  
  950.                 break;
  951.  
  952.             case SLIDER_KIND:
  953.             {
  954.                 BOOL CheckIt;
  955.  
  956.                 Node->Width        = 6 + Node->Chars * Handle->GlyphWidth + 6;
  957.                 Node->Height    = 2 + Handle->GlyphHeight + 2;
  958.  
  959.                 if(Node->DefaultSize)
  960.                     Node->Height = 3 + Handle->GlyphHeight + 3;
  961.  
  962.                 CheckIt = (!Node->Special.Slider.MaxLevelLen || !Node->Special.Slider.LevelWidth || Handle->Rescaled);
  963.  
  964.                 if(Node->Special.Slider.LevelFormat && CheckIt)
  965.                     LTP_LevelWidth(Handle,Node->Special.Slider.LevelFormat,Node->Special.Slider.DispFunc,Node->Min,Node->Max,&Node->Special.Slider.LevelWidth,&Node->Special.Slider.MaxLevelLen,Node->Special.Slider.FullLevelCheck);
  966.  
  967.                 if(Node->Special.Slider.LevelFormat && !V40)
  968.                 {
  969.                     if(Node->Special.Slider.MaxLevelLen * Handle->RPort.TxWidth < Node->Special.Slider.LevelWidth)
  970.                         Node->Special.Slider.MaxLevelLen = (Node->Special.Slider.LevelWidth + Handle->RPort.TxWidth - 1) / Handle->RPort.TxWidth;
  971.                 }
  972.  
  973.                 if(Node->Special.Slider.LevelFormat && Node->Special.Slider.LevelPlace == PLACETEXT_LEFT && Node->LabelPlace == PLACE_LEFT && Node->Label && CheckIt)
  974.                 {
  975.                     LONG    space,len;
  976.                     STRPTR    Buffer;
  977.  
  978.                     space = TextLength(&Handle->RPort," ",1);
  979.                     space = (Node->Special.Slider.LevelWidth + space - 1) / space;
  980.  
  981.                     if(!V40 && (Handle->RPort.TxFlags & FPF_PROPORTIONAL))
  982.                     {
  983.                         Node->Special.Slider.MaxLevelLen++;
  984.  
  985.                         space++;
  986.                     }
  987.  
  988.                     if(Node->Special.Slider.OriginalLabel)
  989.                         LTP_Free(Handle,Node->Label,strlen(Node->Label) + 1);
  990.                     else
  991.                         Node->Special.Slider.OriginalLabel = Node->Label;
  992.  
  993.                     len = strlen(Node->Special.Slider.OriginalLabel);
  994.  
  995.                     if(Buffer = LTP_Alloc(Handle,len + space + 1))
  996.                     {
  997.                         strcpy(Buffer,Node->Special.Slider.OriginalLabel);
  998.  
  999.                         while(space > 0)
  1000.                         {
  1001.                             Buffer[len] = ' ';
  1002.                             len++;
  1003.                             space--;
  1004.                         }
  1005.  
  1006.                         Buffer[len] = 0;
  1007.  
  1008.                         Node->Label            = Buffer;
  1009.                         Node->LabelWidth    = LT_LabelWidth(Handle,Node->Label);
  1010.                     }
  1011.                     else
  1012.                         break;
  1013.                 }
  1014.  
  1015.                 if(Node->LabelChars * Handle->GlyphWidth > Node->LabelWidth)
  1016.                     Node->LabelWidth = Node->LabelChars * Handle->GlyphWidth;
  1017.  
  1018.                 break;
  1019.             }
  1020.  
  1021.             case TEXT_KIND:
  1022.  
  1023.                 if(Node->Special.Text.Text && !Node->Special.Text.SizeLocked)
  1024.                     Max = TextLength(&Handle->RPort,Node->Special.Text.Text,strlen(Node->Special.Text.Text));
  1025.                 else
  1026.                     Max = 0;
  1027.  
  1028.                 Width = Node->Chars * Handle->GlyphWidth;
  1029.  
  1030.                 if(!Node->Special.Text.SizeLocked && Node->Special.Text.LockSize)
  1031.                 {
  1032.                     LONG Chars = (Width + Handle->GlyphWidth - 1) / Handle->GlyphWidth;
  1033.  
  1034.                     if(Chars > Node->Chars)
  1035.                         Node->Chars = Chars;
  1036.  
  1037.                     Max = Width = Node->Chars * Handle->GlyphWidth;
  1038.                 }
  1039.  
  1040.                 if(Max > Width)
  1041.                     Width = Max;
  1042.  
  1043.                 Node->Width        = 6 + Width + 6;
  1044.                 Node->Height    = 3 + Handle->GlyphHeight + 3;
  1045.  
  1046.                 if(Node->Special.Text.UsePicker)
  1047.                     Node->Width += LTP_GetPickerSize(Handle);
  1048.  
  1049.                 if(Node->Special.Text.LockSize)
  1050.                     Node->Special.Text.SizeLocked = TRUE;
  1051.  
  1052.                 break;
  1053.  
  1054.             case NUMBER_KIND:
  1055.             case INTEGER_KIND:
  1056.             case STRING_KIND:
  1057.             case PASSWORD_KIND:
  1058.             case FRACTION_KIND:
  1059.  
  1060.                 Node->Width        = 6 + Node->Chars * Handle->GlyphWidth + 6;
  1061.                 Node->Height    = 3 + Handle->GlyphHeight + 3;
  1062.  
  1063.                 if(Node->Type == STRING_KIND && Node->Special.String.UsePicker)
  1064.                     Node->Width += LTP_GetPickerSize(Handle);
  1065.  
  1066.                 if((Node->Type == INTEGER_KIND && Node->Special.Integer.UseIncrementers) || (Node->Type == FRACTION_KIND && Node->Special.String.IncrementerHook))
  1067.                     Node->Width += 2 * (4 + Handle->GlyphWidth + 4);
  1068.  
  1069.                 break;
  1070.         }
  1071.  
  1072.         if(Node->LabelWidth > Node->Width && (Node->LabelPlace == PLACE_ABOVE || Node->LabelPlace == PLACE_BELOW))
  1073.             Node->Width = Node->LabelWidth;
  1074.     }
  1075. }
  1076.